#ifndef AVALON_UIDSERVER_HPP
#define AVALON_UIDSERVER_HPP
#include "Avalon/IO/ConnectionState.hpp"
#include "Avalon/ServiceLocator/DirectoryEntry.hpp"
#include "Avalon/ServiceLocator/ServiceLocator.hpp"
#include "Avalon/ServiceLocator/ServiceLocatorServices.hpp"
#include "Avalon/Services/ServerMixin.hpp"
#include "Avalon/Services/ServiceNode.hpp"
#include "Avalon/SignalHandling/ConnectionGroup.hpp"
#include "Avalon/SignalHandling/TaskSignalHandler.hpp"
#include "Avalon/UidService/UidServices.hpp"

namespace Avalon {
namespace UidService {

  /*! \class UidServer
   *  \brief Generates unique identifiers.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class UidServer : private Services::ServerMixin<UidServer, UidClientChannel> {
    public:

      //! Constructs a UidServer.
      /*!
        \param serviceClient A ServiceLocatorClient connected to an Avalon
                             service network.
        \param dataStore The UidDataStore to use.
        \param connection An unused ServerConnection.
        \param dataShuttleFactory Specifies the type of serialization to use.
        \param heartbeatTimer The Timer used for heartbeats.
        \param timeout The Connection timeout.
        \param threadPool The ThreadPool used for requests.
      */
      UidServer(ServiceLocator::ServiceLocatorClient* serviceClient,
        UidDataStore* dataStore, IO::ServerConnection* connection,
        Serialization::DataShuttleFactory* dataShuttleFactory,
        Threading::Timer* heartbeatTimer,
        boost::posix_time::time_duration timeout,
        Threading::ThreadPool& threadPool);

      virtual ~UidServer();

      //! Returns <code>true</code> iff the UidServer is connected.
      bool IsConnected() const;

      //! Starts the UidServer.
      /*!
        \throw IOException if an IO operation fails.
      */
      void Start();

      //! Closes the UidServer.
      void Close();

    private:
      typedef ServerMixin<UidServer, UidClientChannel> ServerMixin;
      friend class ServerMixin;
      mutable boost::mutex m_mutex;
      boost::scoped_ptr<UidDataStore> m_dataStore;
      IO::ConnectionState m_dataStoreState;
      SignalHandling::TaskSignalHandler m_signalHandler;

      void HandleCloseResources();
      void OnDataStoreClosed();
      void OnReserveUidsRequest(
        const Services::RequestToken<ReserveUidsService>& request,
        long long blockSize);
  };
}
}

#endif // AVALON_UIDSERVER_HPP
